package dragon.modules.system.org.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import dragon.core.db.DBUtil;
import dragon.core.db.DML;
import dragon.core.exception.ExceptionHandler;
import dragon.core.system.dao.OrgDao;
import dragon.core.system.po.SysOrg;
import dragon.core.util.Reflect;
import dragon.core.util.StringUtils;
import ejp.Database;

public class OrgDaoImpl implements OrgDao {

	/*
	 * (non-Javadoc)
	 * 
	 * @see dragon.modules.system.org.dao.OrgDao#getOrgsByIds(java.lang.String, boolean)
	 */
	@Override
	public List<SysOrg> getOrgsByIds(String ids, boolean includeStopData) throws ExceptionHandler {
		String sql = "select * from " + SysOrg.tableName + " where id in (" + ids + ")";
		if (!includeStopData) {
			sql += " and state='1'";
		}
		sql += " order by depth,ordernum,id asc";

		List<Map<String, Object>> list = DML.query(sql);
		List<SysOrg> orgs = new ArrayList<SysOrg>(list.size());
		for (Map<String, Object> map : list) {
			SysOrg sd = new SysOrg();
			Reflect.map2Obj(map, sd);
			orgs.add(sd);
		}
		list = null;
		return orgs;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dragon.modules.system.org.dao.OrgDao#getOrg(int)
	 */
	@Override
	public SysOrg getOrg(int id) throws ExceptionHandler {
		return DML.loadObject(SysOrg.class, "where id=?", id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dragon.modules.system.org.dao.OrgDao#getOrg(ejp.Database, int)
	 */
	@Override
	public SysOrg getOrg(Database db, int id) throws ExceptionHandler {
		return DML.loadObject(db, SysOrg.class, "where id=?", id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dragon.modules.system.org.dao.OrgDao#changeOrgState(java.lang.String[], java.lang.String)
	 */
	@Override
	public int changeOrgState(String[] ids, String state) throws ExceptionHandler {
		int count = 0;
		for (String id : ids) {
			count += DML.executeUpdate("update " + SysOrg.tableName + " set state='" + state + "' where id=" + id + " or idpath like '%/" + id + "/%'");
		}
		return count;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dragon.modules.system.org.dao.OrgDao#namePathRepair(ejp.Database, int, java.lang.String, java.lang.String)
	 */
	@Override
	public void namePathRepair(Database db, int id, String oldName, String newName) throws ExceptionHandler {
		DML.executeUpdate(db, "update " + SysOrg.tableName + " set namepath=replace(namepath,'/" + oldName + "/','/" + newName + "/') where id=" + id + " or idpath like '%/" + id + "/%' ");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dragon.modules.system.org.dao.OrgDao#codePathRepair(ejp.Database, int, java.lang.String, java.lang.String)
	 */
	@Override
	public void codePathRepair(Database db, int id, String oldCode, String newCode) throws ExceptionHandler {
		DML.executeUpdate(db, "update " + SysOrg.tableName + " set codepath=replace(codepath,'/" + oldCode + "/','/" + newCode + "/') where id=" + id + " or idpath like '%/" + id + "/%' ");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dragon.modules.system.org.dao.OrgDao#changeParent(int, int)
	 */
	@Override
	public void changeParent(int id, int target) throws ExceptionHandler {
		// 获取部门
		SysOrg org = getOrg(id);

		// 加载新的父节点数据
		SysOrg newParent = getOrg(target);
		if (newParent == null) {
			newParent = new SysOrg();
			newParent.setId(0);
			newParent.setIdpath("/");
			newParent.setCodepath("/");
			newParent.setNamepath("/");
		}

		// 深度差
		int depth_odds = newParent.getDepth() - org.getDepth() + 1;

		Database db = DBUtil.getDatabase();
		DML.beginTransaction(db);
		DML.executeUpdate(db, "update " + SysOrg.tableName + " set pid=" + newParent.getId() + " where id=" + id);
		if (org.getPid() == 0) {
			// 删除路径最后一个斜线，避免路径相加出现双斜线
			StringBuffer sb_idpath = new StringBuffer(newParent.getIdpath());
			newParent.setIdpath(sb_idpath.deleteCharAt(sb_idpath.lastIndexOf("/")).toString());
			StringBuffer sb_namepath = new StringBuffer(newParent.getNamepath());
			newParent.setNamepath(sb_namepath.deleteCharAt(sb_namepath.lastIndexOf("/")).toString());
			StringBuffer sb_codepath = new StringBuffer(newParent.getCodepath());
			newParent.setCodepath(sb_codepath.deleteCharAt(sb_codepath.lastIndexOf("/")).toString());
			DML.executeUpdate(db,
					"update " + SysOrg.tableName + " set idpath='" + newParent.getIdpath() + "'||idpath,codepath='" + newParent.getCodepath() + "'||codepath,namepath='" + newParent.getNamepath()
							+ "'||namepath,depth=depth+" + depth_odds + " where id=" + id + " or idpath like '%/" + id + "/%'");
		} else {
			// 加载旧的父节点数据
			SysOrg oldParent = getOrg(org.getPid());
			DML.executeUpdate(db,
					"update " + SysOrg.tableName + " set idpath=replace(idpath,'" + oldParent.getIdpath() + "','" + newParent.getIdpath() + "'),codepath=replace(codepath,'" + oldParent.getCodepath()
							+ "','" + newParent.getCodepath() + "'),namepath=replace(namepath,'" + oldParent.getNamepath() + "','" + newParent.getNamepath() + "'),depth=depth+" + depth_odds
							+ "  where id=" + id + " or idpath like '%/" + id + "/%'");
			oldParent = null;
		}
		DML.endTransaction(db);
		db = null;

		newParent = null;
		org = null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see dragon.modules.system.org.dao.OrgDao#isExist(int, int, java.lang.String, java.lang.String)
	 */
	@Override
	public boolean isExist(int id, int pid, String code, String name) throws ExceptionHandler {
		String sql = null;
		if (!StringUtils.isEmpty(code)) {
			sql = "select count(*)n from " + SysOrg.tableName + " where code=? and pid=" + pid + " and id!=" + id;
			return !DML.prepareQuery("", sql, code.trim()).get(0).get("N").toString().equals("0");
		} else {
			sql = "select count(*)n from " + SysOrg.tableName + " where name=? and pid=" + pid + " and id!=" + id;
			return !DML.prepareQuery("", sql, name.trim()).get(0).get("N").toString().equals("0");
		}
	}

}
